package com.sff.net {
	
	import com.sff.core.ILoadable;
	import com.sff.core.IProgressable;
	import com.sff.core.sff_internal;
	import com.sff.events.LoaderErrorEvent;
	import com.sff.events.LoaderProgressEvent;
	import com.sff.events.LoaderStatusEvent;
	
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.StatusEvent;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;
	import flash.utils.getQualifiedClassName;
	
	use namespace sff_internal;	
	
	public class BaseLoaderItem extends EventDispatcher implements ILoadable, IProgressable {
	
		private var _ed 					: IEventDispatcher;
		public var params 					: Object;
		
		sff_internal var _request 			: URLRequest;
		sff_internal var _context 			: LoaderContext;
		sff_internal var _statusMessage 	: String;
		
		protected var size : int = -1;
		
		public function getLength () : uint {
			return uint( size );
		}
		
		public function dispose () : void {
			
		}
		
		public function get request() : URLRequest {	
			return _request;
		}
		 		
		public function get context() : LoaderContext {	
			return _context;
		}

		public function BaseLoaderItem ( request : URLRequest, context : LoaderContext = null, params : Object = null, statusMessage : String = null) : void {
			super( null );
			
			_request = request;
			_context = context;
			_statusMessage = statusMessage;
			
			this.params = params;
		}
		
		public function execute () : void {
			sendStatus(  new StatusEvent ( StatusEvent.STATUS, false, false, _statusMessage || (request.url ), "status" ) );
			
			if( request.url == "" ) {
				sendError( new ErrorEvent( ErrorEvent.ERROR, false, false, "URL not found" ) );
			}	
		}
		
		override public function toString() : String {
			return "["+getQualifiedClassName( this ) + "] url " + (( _request != null ) ? _request.url : "null" );
		}
		
		
		protected function register ( ed : IEventDispatcher ) : void {
			if( _ed ) unregister();
			_ed = ed;
			
			ed.addEventListener( Event.INIT							, onInit );
			ed.addEventListener( Event.COMPLETE						, sendComplete );
			ed.addEventListener( ProgressEvent.PROGRESS				, sendProgress ) ;
			ed.addEventListener( IOErrorEvent.IO_ERROR				, sendError );
			ed.addEventListener( SecurityErrorEvent.SECURITY_ERROR	, sendError );
			ed.addEventListener( Event.OPEN							, sendOpen );
		}
		
		protected function unregister ( ) : void {
			if( ! _ed ) return;
			_ed.removeEventListener( Event.INIT							, onInit );
			_ed.removeEventListener( Event.COMPLETE						, sendComplete );
			_ed.removeEventListener( ProgressEvent.PROGRESS				, sendProgress ) ;
			_ed.removeEventListener( IOErrorEvent.IO_ERROR				, sendError );
			_ed.removeEventListener( SecurityErrorEvent.SECURITY_ERROR	, sendError );
			_ed.removeEventListener( Event.OPEN							, sendOpen );
			_ed = null;
		}
		
		protected function onInit( e : Event ) : void {
			dispatchEvent( e );
		}
				
		public function sendError ( e : ErrorEvent ) : void {
			dispatchEvent( new LoaderErrorEvent( ErrorEvent.ERROR, e.text ) );
		}
		
		public function sendProgress (e : ProgressEvent) : void {
			dispatchEvent( new LoaderProgressEvent( LoaderProgressEvent.ITEM_PROGRESS, false, false, e.bytesLoaded, e.bytesTotal, getLength() ) );
			dispatchEvent( e );
		}
		
		public function sendOpen (e : Event) : void {
			dispatchEvent( e );
		}
		
		public function sendComplete (e : Event) : void {
			unregister( );
			dispatchEvent( e );
		}

		public function sendStatus ( e : StatusEvent ) : void {
			dispatchEvent( new LoaderStatusEvent ( StatusEvent.STATUS, _statusMessage || (request.url )));
		}
	}
}